package org.rambadger.command.providers;

import org.mongojack.DBCursor;

/**
 * Container for information relating to pagination.
 */
public class Pagination {
    /**
     * Creates a new Pagination object. This will usually only be called by {@link PaginationProvider}
     *
     * @param page the page number
     * @param perPage the number of results per page
     */
    public Pagination(int page, int perPage) {
        this.page = page;
        this.perPage = perPage;
    }

    /**
     * The 1-indexed page number of the page to display.
     */
    public int page;
    /**
     * The number of results to display per page.
     */
    public int perPage;

    /**
     * Sets the {@link DBCursor#limit(int) limit} and {@link DBCursor#skip(int) skip} of a {@link DBCursor curor} based on the contained information.
     *
     * @param cursor the cursor
     */
    public void seekCursorToPage(DBCursor<?> cursor) {
        cursor.limit(perPage).skip((page-1)*perPage);
    }

    /**
     * Returns a {@link PageInfo} object that contains additional information derived from the cursor. (Mainly the number of pages)
     * @param cursor the cursor to get information from.
     * @return the object containing the extended information
     */
    public PageInfo infoOn(DBCursor<?> cursor) {
        int found = cursor.count();
        return new PageInfo(page, perPage, found);
    }

    /**
     * Holds extended information on pagination derived from a {@link DBCursor cursor}
     */
    public static class PageInfo {
        /**
         * The page number.
         */
        public int page;
        /**
         * The number of results per page.
         */
        public int perPage;
        /**
         * The number of results found.
         */
        public int numberFound;

        /**
         * Instantiates a new PageInfo object.
         *
         * @param page the page
         * @param perPage the per page
         * @param numberFound the number found
         */
        public PageInfo(int page, int perPage, int numberFound) {
            this.page = page;
            this.perPage = perPage;
            this.numberFound = numberFound;
        }

        /**
         * Gets number of pages found.
         *
         * @return the number of pages found
         */
        public int getNumberOfPagesFound() {
            return (int)Math.ceil((double)numberFound/(double)perPage);
        }
    }
}
